(function($) {
	$.fn.countTo = function(options) {
		options = options || {};
		return $(this)
				.each(
						function() {
							var settings = $.extend({}, $.fn.countTo.defaults,
									{
										from : $(this).data('from'),
										to : $(this).data('to'),
										speed : $(this).data('speed'),
										refreshInterval : $(this).data(
												'refresh-interval'),
										decimals : $(this).data('decimals')
									}, options);
							var loops = Math.ceil(settings.speed
									/ settings.refreshInterval), increment = (settings.to - settings.from)
									/ loops;
							var self = this, $self = $(this), loopCount = 0, value = settings.from, data = $self
									.data('countTo')
									|| {};
							$self.data('countTo', data);
							if (data.interval) {
								clearInterval(data.interval);
							}
							data.interval = setInterval(updateTimer,
									settings.refreshInterval);
							render(value);
							function updateTimer() {
								value += increment;
								loopCount++;
								render(value);
								if (typeof (settings.onUpdate) == 'function') {
									settings.onUpdate.call(self, value);
								}
								if (loopCount >= loops) {
									$self.removeData('countTo');
									clearInterval(data.interval);
									value = settings.to;
									if (typeof (settings.onComplete) == 'function') {
										settings.onComplete.call(self, value);
									}
								}
							}
							function render(value) {
								var formattedValue = settings.formatter.call(
										self, value, settings);
								$self.text(formattedValue);
							}
						});
	};
	$.fn.countTo.defaults = {
		from : 0,
		to : 0,
		speed : 1000,
		refreshInterval : 100,
		decimals : 0,
		formatter : formatter,
		onUpdate : null,
		onComplete : null
	};
	function formatter(value, settings) {
		return value.toFixed(settings.decimals);
	}
}(jQuery));